﻿/// <reference path="jquery.min.js" />
/// <reference path="jquery.tools.min.js" />

/// jquery-json
(function($){var escapeable=/["\\\x00-\x1f\x7f-\x9f]/g,meta={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'};$.toJSON=typeof JSON==='object'&&JSON.stringify?JSON.stringify:function(o){if(o===null){return'null';}
var type=typeof o;if(type==='undefined'){return undefined;}
if(type==='number'||type==='boolean'){return''+o;}
if(type==='string'){return $.quoteString(o);}
if(type==='object'){if(typeof o.toJSON==='function'){return $.toJSON(o.toJSON());}
if(o.constructor===Date){var month=o.getUTCMonth()+1,day=o.getUTCDate(),year=o.getUTCFullYear(),hours=o.getUTCHours(),minutes=o.getUTCMinutes(),seconds=o.getUTCSeconds(),milli=o.getUTCMilliseconds();if(month<10){month='0'+month;}
if(day<10){day='0'+day;}
if(hours<10){hours='0'+hours;}
if(minutes<10){minutes='0'+minutes;}
if(seconds<10){seconds='0'+seconds;}
if(milli<100){milli='0'+milli;}
if(milli<10){milli='0'+milli;}
return'"'+year+'-'+month+'-'+day+'T'+
hours+':'+minutes+':'+seconds+'.'+milli+'Z"';}
if(o.constructor===Array){var ret=[];for(var i=0;i<o.length;i++){ret.push($.toJSON(o[i])||'null');}
return'['+ret.join(',')+']';}
var name,val,pairs=[];for(var k in o){type=typeof k;if(type==='number'){name='"'+k+'"';}else if(type==='string'){name=$.quoteString(k);}else{continue;}
type=typeof o[k];if(type==='function'||type==='undefined'){continue;}
val=$.toJSON(o[k]);pairs.push(name+':'+val);}
return'{'+pairs.join(',')+'}';}};$.evalJSON=typeof JSON==='object'&&JSON.parse?JSON.parse:function(src){return eval('('+src+')');};$.secureEvalJSON=typeof JSON==='object'&&JSON.parse?JSON.parse:function(src){var filtered=src.replace(/\\["\\\/bfnrtu]/g,'@').replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,']').replace(/(?:^|:|,)(?:\s*\[)+/g,'');if(/^[\],:{}\s]*$/.test(filtered)){return eval('('+src+')');}else{throw new SyntaxError('Error parsing JSON, source is not valid.');}};$.quoteString=function(string){if(string.match(escapeable)){return'"'+string.replace(escapeable,function(a){var c=meta[a];if(typeof c==='string'){return c;}
c=a.charCodeAt();return'\\u00'+Math.floor(c/16).toString(16)+(c%16).toString(16);})+'"';}
return'"'+string+'"';};})(jQuery);

// 扩展window对象，提供一些全局的方法 //////////////////////////////////////////
(function (window) {
    // 空方法，什么也不做
    window.noop = function () { };

    // 添加调命令，方便调试
    window.debug = function (message) {
        if ($.isArray(message)) {
            var lines = ["[FancyIdea Debug Array]"];
            for (var i = 0; i < message.length; i++) {
                lines.push(message[i]);
            }
            alert(lines.join("\n"));
        } else if (typeof (message) === "object" && message !== null) {
            var type = message.toString();
            type = type.replace(/^\[object\s+|\]$/g, "");
            var lines = ["[FancyIdea Debug " + type + "]"];
            for (key in message) {
                if (typeof (message[key]) === "function") {
                    lines.push(key + " = (function)");
                } else if (message[key] === null) {
                    lines.push(key + " = (null)");
                } else {
                    lines.push(key + " = " + message[key]);
                }
            }
            alert(lines.join("\n"));
        } else {
            alert("[FancyIdea Debug]\n" + message);
        }
    };

    // 定义日志相关函数
    if (typeof console !== "undefined") {
        window.log = {
            toArray: function() {
                var a = [];
                for (var i = 0; i < arguments.length; i++) {
                    var o = arguments[i];
                    if (typeof o === "object") {
                        a.push($.toJSON(o));
                    } else if (o != undefined) {
                        a.push(o.toString());
                    }
                }
                return a;
            },
            debug: function () { console.log(this.toArray.apply(null, arguments)); },
            info: function () { console.log(this.toArray.apply(null, arguments)); },
            warn: function () { console.warn(this.toArray.apply(null, arguments)); },
            error: function () { console.error(this.toArray.apply(null, arguments)); },
            fatal: function () { console.error(this.toArray.apply(null, arguments)); }
        }
    } else {
        window.log = {
            debug: noop,
            info: noop,
            warn: noop,
            error: noop,
            fatal: noop
        }
    }
})(window);

// 处理window的resize事件 //////////////////////////////////////////////////////
(function (window) {
    window.loadedAppPage = false;
    window.mainHeight = function () {
        return $(window).height() - $(".bottom").height() - $(".main_area").position().top - 2
    };

    $(window).resize(function () {
        if (!window.loadedAppPage) {
            return;
        }

        log.info("Resizing");
        if (window.lastHeight === $(this).height()) {
            return;
        }

        window.lastHeight = $(this).height();
        var jMainArea = $(".main_area");
        var jMenuPanel = $(".menu_panel");
        var jBottomArea = $(".bottom");

        var mainHeight = window.mainHeight();
        $(".content_div").height(mainHeight);
        jMenuPanel.height(mainHeight - $(".user_panel").height()
            - parseInt(jMenuPanel.css("padding-top")) - parseInt(jMenuPanel.css("padding-bottom")));

        if (!!page && typeof page.onResize === "function") {
            page.onResize(mainHeight);
        }
    });
})(window);

// 扩展jQuery对象的方法 ////////////////////////////////////////////////////////
(function (jQuery) {
    var $ = jQuery;
    $.fn.extend({
        hoverable: function () {
            return this.bind("mouseover.fi", function () {
                $(this).addClass("hover");
            }).bind("mouseout.fi", function () {
                $(this).removeClass("hover");
            });
        },
        hoverless: function () {
            return this.unbind("mouseover.fi").unbind("mouseout.fi");
        },
        disableSelect: function () {
            return this.bind("selectstart.fi", function (event) {
                return false;
            });
        },
        makeDateInput: function () {
            return this.dateinput({
                lang: "cn",
                format: "yyyy-mm-dd",
                selectors: true,
                speed: "fast",
                firstDay: 1
            });
        },
        makeButton: function () {
            return this.addClass("button").hoverable();
        }
    });
})(jQuery);

// 将keyCode值转换为ASCII //////////////////////////////////////////////////////
(function () {
    window.keyChar = (function () {
        var ssss = "";
        var SSSS = "";

        // M和m只是标尺, ssss和SSSS变量长度是为了对齐标尺
        var M = "0         1         2         3         4         ";
        var m = "01234567890123456789012345678901234567890123456789";

        // 不带shift的码表
        ssss += "                                                01";
        ssss += "23456789       abcdefghijklmnopqrstuvwxyz     0123";
        ssss += "456789*+ -./                                      ";
        ssss += "                                    ;=,-./`       ";
        ssss += "                   [ ]'                           ";

        // 带shift的码表
        SSSS += "                                                )!";
        SSSS += "@#$%^&*(       ABCDEFGHIJKLMNOPQRSTUVWXYZ     0123";
        SSSS += "456789*+ -./                                      ";
        SSSS += "                                    :+<_>?~      ";
        SSSS += "                   {|}                            ";

        // 将码表拆成字符数组
        var t = ssss.split("");
        var T = SSSS.split("");

        // 将所有空格替换成空字符
        var nullChar = String.fromCharCode(0);
        for (var i = 0; i < t.length; i++) {
            (t[i] === " ") && (t[i] = nullChar);
            (T[i] === " ") && (T[i] = nullChar);
        }

        // 几个需要转义的字符，放在表里会影响排版，所以单独处理
        t[9] = "\t";
        t[13] = "\n";
        t[32] = " ";
        t[220] = "\\";

        T[32] = " ";
        T[222] = '"';

        return function (event, isCheckShift) {
            if (typeof isCheckShift === "undefined") { isCheckShift = true; }
            if (!!isCheckShift && event.shiftKey) {
                return T[event.keyCode];
            } else {
                return t[event.keyCode];
            }
        };
    })();

    window.isCtrlKey = (function () {
        return function (keyCode) {
            // 8        - 退格
            // 9        - Tab
            // 13       - 回车
            // 16~18    - Shift, Ctrl, Alt
            // 37~40    - 左上右下
            // 35~36    - End Home
            // 46       - Del
            // 112~123  - F1-F12
            switch (keyCode) {
                case 8: case 9: case 13:
                case 16: case 17: case 18:
                case 37: case 38: case 39: case 40:
                case 35: case 36: case 46:
                    return true;
                default:
                    if (keyCode >= 112 && keyCode <= 123) {
                        return true;
                    }
                    return false;
            }
        }
    })();
})();

// 产生app对象，用于处理应用相关的控制 /////////////////////////////////////////
(function (jQuery, window) {
    var $ = jQuery;
    var app = {};
    window.app = app;

    // 扩展预置变量(函数方式) //////////////////////////////////////////////
    app.vars = {
        get: function (key) {
            if (!key) {
                return "";
            }
            key = $.trim(key.toString()).replace(/^var:|;$/g, "");
            var f = this[key];
            if (typeof f === "function") {
                return f.call(this);
            } else {
                return "";
            }
        },
        today: function () {
            return Date.today().toString("yyyy-MM-dd");
        },
        now: function () {
            return new Date().toString("HH:mm");
        },
        user_name: function () {
            return "[" + app.userinfo.id + "] " + app.userinfo.name;
        },
        user_department: function() {
            return "[" + app.userinfo.departId + "] " + app.userinfo.department;
        }
    };

    // 默认的Ajax配置及方法 ////////////////////////////////////////////////
    $.extend(app, {
        ajax: function (url) {
            var params, callback, dataType;
            for (var i = 1; i < arguments.length; i++) {
                switch (typeof arguments[i]) {
                    case "object":
                        if (params === undefined) { params = arguments[i]; }
                        break;
                    case "function":
                        if (callback === undefined) { callback = arguments[i]; }
                        break;
                    case "string":
                        if (dataType === undefined) { dataType = arguments[i]; }
                        break;
                }
            }

            if (typeof callback != "function") {
                callback = noop;
            }

            if (!dataType) {
                dataType = "xml";
            }

            log.debug(url, params);
            log.info(url + "?" + $.param(params || {}, true));
            $.ajax(encodeURI(url), {
                dataType: dataType,
                data: params,
                cache: false,
                traditional: true,
                success: function (data, textStatus, jqXHR) {
                    callback(data, textStatus, jqXHR);
                },
                error: function (jqXHR, textStatus, errorThrown) {
                    callback(null, jqXHR, textStatus, errorThrown);
                }
            });
        },

        ajaxHtml: function(url, params, callback) {
            this.ajax(url, params, callback, "html");
        },

        ajaxXml: function (url, params, callback) {
            this.ajax(url, params, callback, "xml");
        },

        ajaxScript: function (url, params, callback) {
            this.ajax(url, params, callback, "script");
        }
    });

    // 为app扩展工具方法
    (function(jQuery, window) {
        var $ = jQuery;

        app.$ = app.jQuery = function(obj) {
            if (obj instanceof jQuery) {
                return obj;
            } else {
                return $(obj);
            }
        };
    })(jQuery, window);

    // 控制载入状态的和消息的显示/隐藏 /////////////////////////////////////
    $.extend(app, {
        loading: {
            show: function (message) {
                $("#progress_icon").show();
                this.message(message);
            },
            hide: function (message) {
                $("#progress_icon").hide();
                if (message !== false) {
                    this.message(message || "");
                }
            },
            message: function (message) {
                if (!!message) {
                    $(".progress_message").text(message);
                } else if (message === "") {
                    $(".progress_message").text("");
                }
            }
        }
    });

    // 验证和输入限制 //////////////////////////////////////////////////////
    (function () {
        app.validator = {
            init: function ($dom) {
                var me = this;
                $dom.each(function () {
                    me.cfgVerify($(this));
                    me.cfgConvert($(this));
                });
            },
            isType: function (c) {
                var type = arguments[1];
                if (arguments.length > 2) {
                    for (var i = 2; i < arguments.length; i++) {
                        type += "|" + arguments[i];
                    }
                    type = "(?:" + type + ")";
                }

                return new RegExp("\\bt_" + type + "\\b").test(c);
            },
            cfgVerify: function ($dom) {
                var c = $dom.attr("class");

                var config = $dom.data("config");
                var isRequired;
                if (!config) {
                    isRequired = false;
                } else {
                    isRequired = config.required;
                }

                var limitRegex = null;
                var verifyRegex = null;
                var message = null;
                if (this.isType(c, "number")) {
                    limitRegex = /[\d]/;
                    verifyRegex = /^\d+$/;
                    message = "请输入完全由0-9数字组成的字符串。"
                } else if (this.isType(c, "decimal")) {
                    limitRegex = /[-\d\.]/;
                    verifyRegex = /^-?\d+(?:\.\d+)?$/;
                    message = "请输入正确格式的实数，请检查减号及小数点位置是否正确。"
                } else if (this.isType(c, "date")) {
                    limitRegex = /[\d-]/;
                    verifyRegex = /^\d{4}-\d{1,2}-\d{1,2}$/;
                    message = "请按yyyy-M-d或yyyy-MM-dd格式输入日期。"
                } else if (this.isType(c, "time")) {
                    limitRegex = /[\d:]/;
                    verifyRegex = /^\d{1,2}:\d{1,2}(?:\d{1,2})?$/;
                    message = "请按HH:mm:ss或HH:mm格式输入时间。"
                } else if (this.isType(c, "datetime")) {
                    limitRegex = /[\d-:]/;
                    verifyRegex = /^\d{4}-\d{1,2}-\d{1,2}\s+\d{1,2}:\d{1,2}(?:\d{1,2})?$/;
                    message = "请按yyyy-M-d或yyyy-MM-dd格式输入日期，按HH:mm:ss或HH:mm格式输入时间，且日期和时间之间用空格分隔。"
                } else if (this.isType(c, "phone")) {
                    limitRegex = /[\d\+-]/;
                    verifyRegex = /^\+?\d+(?:-\d+)*$/;
                    message = "电话号码可用-号对号码分组，但不能连续使用-号。注意+号只能出现在最前面。";
                } else if (this.isType(c, "ascii", "code")) {
                    limitRegex = /[a-z0-9]/i;
                    verifyRegex = /^[a-z0-9]+$/i;
                    message = "这里仅允许输入大小写字母和数字。";
                } else {
                    if (!isRequired) { return; }
                }

                if (limitRegex != null) {
                    $dom.unbind("keydown.fi_v").bind("keydown.fi_v", function (e) {
                        if (e.altKey || e.ctrlKey) {
                            return;
                        }

                        if (isCtrlKey(e.keyCode)) {
                            return;
                        }

                        var char = keyChar(e);
                        return limitRegex.test(char);
                    });
                }

                if (isRequired || verifyRegex != null) {
                    $dom.bind("change.fi_v", function (e) {
                        var me = $(this);
                        var value = me.val();
                        var err = me.nextUntil(".err").andSelf().next(".err");

                        var showErr = function (s) {
                            if (err.length < 1) {
                                err = $("<div>").addClass("err").appendTo(me.parent("td"));
                            }
                            err.text(s).show();
                        };

                        err.hide();
                        if (value === "") {
                            if (isRequired) {
                                showErr("此项数据不可缺省，请填写此项数据。");
                            }
                        } else if (verifyRegex != null && !verifyRegex.test(value)) {
                            showErr(message);
                        }
                    }).bind("blur.fi_v_ch", function () {
                        if ($(this).val() === "") {
                            $(this).change();
                        }
                    });
                }
            },
            cfgConvert: function ($dom) {
                $dom.unbind("blur.fi_v").filter(".t_code").bind("blur.fi_v", function () {
                    $(this).val($(this).val().toUpperCase());
                });
            }
        };
    })();

    // 应用对话框 //////////////////////////////////////////////////////////
    (function () {
        app.dialog = {
            // 默认参数 ////////////////////////////////////////////////
            option: function (ext) {
                return $.extend({
                    api: true,
                    speed: "fast",
                    fadeInSpeed: "fast",
                    top: "center",
                    expose: {
                        color: "#0B4482",
                        opacity: 0.8,
                        loadSpeed: "fast",
                        closeSpeed: "fast"
                    }
                }, ext);
            },

            // 消息对话框 //////////////////////////////////////////////
            message: function (isHtml, text, title, callback) {
                if (typeof isHtml !== "boolean") {
                    callback = title;
                    title = text;
                    text = isHtml;
                    isHtml = false;
                }

                if (typeof title === "function") {
                    callback = title;
                    title = undefined;
                }

                var d = $(".dialogs .message.dialog");
                d.children(".title").text(title || "电子评税系统");
                if (isHtml) {
                    d.children(".content").html(text);
                } else {
                    d.children(".content").text(text);
                }

                var overlay = this.message.overlay;
                if (!overlay) {
                    d.find(".buttons a").each(function () {
                        this.hideFocus = true;
                    });

                    overlay = this.message.overlay = d.overlay(this.option({
                        close: ".b_ok"
                    }));
                }
                overlay.onClose = (typeof callback === "function") ? callback : undefined;
                overlay.load();
            },

            // 确认对话框 //////////////////////////////////////////////
            confirm: function (isHtml, text, title, onOk, onCancel) {
                if (typeof isHtml !== "boolean") {
                    onCancel = onOk;
                    onOk = title;
                    title = text;
                    text = isHtml;
                    isHtml = false;
                }

                if (typeof title === "function") {
                    onCancel = onOk;
                    onOk = title;
                    title = undefined;
                };

                var d = $(".dialogs .confirm.dialog");
                d.children(".title").text(title || "电子评税系统");
                if (isHtml) {
                    d.children(".content").html(text);
                } else {
                    d.children(".content").text(text);
                }

                var overlay = this.confirm.overlay;
                if (!overlay) {
                    d.find(".buttons a").each(function () {
                        this.hideFocus = true;
                    });

                    overlay = this.confirm.overlay = d.overlay(this.option({
                        close: ".b_cancel",
                        onClose: function () {
                            if (this.isOk) {
                                if (!!overlay.events && typeof overlay.events.onOk === "function") {
                                    overlay.events.onOk();
                                }
                            } else {
                                if (!!overlay.events && typeof overlay.events.onCancel === "function") {
                                    overlay.events.onCancel();
                                }
                            }
                        }
                    }));
                }

                overlay.isOk = false;
                overlay.events = {
                    onOk: onOk,
                    onCancel: onCancel
                };

                d.find(".b_ok").unbind("click").click(function () {
                    overlay.isOk = true;
                    overlay.close();
                });

                overlay.load();
            },

            // 修改密码对话框 //////////////////////////////////////////
            changePassword: function () {
                var d = $(".dialogs .change_pass.dialog");
                d.find("input").val("");
                var overlay = this.changePassword.overlay;
                if (!overlay) {
                    d.find(".buttons a").each(function () {
                        this.hideFocus = true;
                    });

                    overlay = this.changePassword.overlay = d.overlay(this.option({
                        close: ".b_cancel",
                        closeOnEsc: true,
                        closeOnClick: false,
                        onLoad: function () {
                            d.find(".pass_old").focus();
                        }
                    }));

                    d.find(".pass_old").keypress(function (e) {
                        if (e.keyCode === 13) {
                            d.find(".pass_new").select().focus();
                        }
                    });

                    d.find(".pass_new").keypress(function (e) {
                        if (e.keyCode === 13) {
                            d.find(".pass_new_again").select().focus();
                        }
                    });

                    d.find(".pass_new_again").keypress(function (e) {
                        if (e.keyCode === 13) {
                            d.find(".b_ok").click();
                        }
                    });

                    d.find(".b_ok").click(function () {
                        if (d.find(".pass_new").val() === d.find(".pass_new_again").val()) {
                            app.ajaxXml("core/bll/税务机关和人员.ashx", {
                                fi_act: "UpdatePassword",
                                m: "self",
                                "旧密码": d.find(".pass_old").val(),
                                "新密码": d.find(".pass_new").val()
                            }, function (xml) {
                                var isSucc = false;
                                overlay.close();
                                if (!!xml) {
                                    var $xml = $(xml);
                                    if ($xml.find("response > code").text() === "0") {
                                        setTimeout(function () {
                                            app.dialog.message("修改密码成功");
                                        }, 200);
                                        isSucc = true;
                                    }
                                }
                                if (!isSucc) {
                                    setTimeout(function () {
                                        app.dialog.message("修改密码失败，请检查旧密码是否正确，然后重试");
                                    }, 200);
                                }
                            });
                        } else {
                            overlay.close();
                            setTimeout(function () {
                                app.dialog.message("两次输入的密码不一致", function () {
                                    setTimeout(function () {
                                        overlay.load();
                                        d.find(".pass_new").focus();
                                    }, 200);
                                });
                            }, 200);
                        }
                    });
                }

                overlay.load();
            },

            // 重新设置密码对话框（管理员为用户设置） //////////////////
            resetPassword: function (isRunOnServer, userId, callback) {
                if (typeof isRunOnServer !== "boolean") {
                    callback = userId;
                    userId = isRunOnServer;
                    isRunOnServer = true;
                }

                if (typeof userId === "function") {
                    callback = userId;
                    userId = isRunOnServer;
                }

                var d = $(".dialogs .reset_pass.dialog");
                d.find("input").val("");
                var overlay = this.resetPassword.overlay;
                if (!overlay) {
                    d.find(".buttons a").each(function () {
                        this.hideFocus = true;
                    });

                    overlay = this.resetPassword.overlay = d.overlay(this.option({
                        close: ".b_cancel",
                        closeOnEsc: true,
                        closeOnClick: false,
                        onLoad: function () {
                            d.find(".pass_new").focus();
                        }

                    }));

                    d.find(".pass_new").keypress(function (e) {
                        if (e.keyCode === 13) {
                            d.find(".pass_new_again").select().focus();
                        }
                    });

                    d.find(".pass_new_again").keypress(function (e) {
                        if (e.keyCode === 13) {
                            d.find(".b_ok").click();
                        }
                    });

                    d.find(".b_ok").click(function () {
                        if (d.find(".pass_new").val() === d.find(".pass_new_again").val()) {
                            if (isRunOnServer) {
                                app.ajaxXml("core/bll/税务机关和人员.ashx", {
                                    fi_act: "UpdatePassword",
                                    m: "manager",
                                    "税务人员代码": userId,
                                    "新密码": d.find(".pass_new").val()
                                }, function (xml) {
                                    overlay.close();
                                    var isSucc = false;
                                    if (!!xml) {
                                        var $xml = $(xml);
                                        if ($xml.find("response > code").text() === "0") {
                                            setTimeout(function () {
                                                app.dialog.message("修改密码成功");
                                            }, 200);
                                            isSucc = true;
                                        }
                                    }
                                    if (!isSucc) {
                                        setTimeout(function () {
                                            app.dialog.message("修改密码失败。");
                                        }, 200);
                                    }
                                });
                            } else {
                                overlay.events.onReset(true, d.find(".pass_new").val());
                                overlay.close();
                            }
                        } else {
                            overlay.close();
                            setTimeout(function () {
                                app.dialog.message("两次输入的密码不一致", function () {
                                    setTimeout(function () {
                                        overlay.load();
                                        d.find(".pass_new").focus();
                                    }, 200);
                                });
                            }, 200);
                        }
                    });
                }

                overlay.data = {
                    userId: userId
                };

                overlay.events = {
                    onReset: typeof callback === "function" ? callback : noop
                };

                overlay.load();
            },

            // 设置权限对话框 //////////////////////////////////////////
            perms: function (initValue, callback) {
                if (typeof initValue === "function") {
                    callback = initValue;
                    initValue = null;
                }
                initValue = initValue || "";

                var d = $(".dialogs .perm.dialog");
                var overlay = this.perms.overlay;
                if (!overlay) {
                    d.find(".buttons a").each(function () {
                        this.hideFocus = true;
                    });

                    overlay = this.perms.overlay = d.overlay(this.option({
                        close: ".b_cancel",
                        onClose: function () {
                            var perm = null;
                            if (this.isOk) {
                                var perms = [];
                                perm = d.find(":checkbox:checked").each(function () {
                                    if ($(this).siblings("ul").length === 0) {
                                        perms.push($(this).val());
                                    }
                                });
                                this.events.callback(perms.join(";"));
                            } else {
                                this.events.callback(null);
                            }
                        }
                    }));

                    d.find(".b_ok").unbind("click").click(function () {
                        overlay.isOk = true;
                        overlay.close();
                    });
                }
                overlay.isOk = false;

                var initPerms = function () {
                    d.find(":checkbox").attr("checked", false);
                    if (typeof initValue !== "string" || !initValue) {
                        return;
                    }

                    var perms = initValue.split(/[;, ]+/);
                    d.find("li:not(:has(ul))").children(":checkbox").each(function () {
                        if ($.inArray($(this).val(), perms) >= 0) {
                            $(this).attr("checked", true).change();
                        }
                    });
                };

                // 如果权限列表为空，载入权限
                if (d.find(":checkbox:first").length < 1) {
                    app.ajaxXml("core/bll/税务机关和人员.ashx", {
                        fi_act: "GetPowerList"
                    }, function (xml) {
                        if (!xml) {
                            if (overlay.isOpened()) {
                                alert("未能成功加载权限列表，请稍后重试...");
                                overlay.close();
                            }
                            return;
                        }

                        var $xml = $(xml);
                        var context = $("<ul>");
                        var root = $("<li><input type='checkbox' id='P_0'/><label for='P_0'>所有权限</label></li>")
                            .appendTo(context).disableSelect();
                        root.children(":checkbox").val(0).get(0).hideFocus = true;
                        root.children("label").get(0).hideFocus = true;

                        var createLi = function (item) {
                            var t = item.children("Text").text();
                            var v = item.children("Value").text();
                            var id = "P_" + v;
                            var li = $("<li>").append($("<input type='checkbox'>").attr("id", id).val(v))
                                .append($("<label>").attr("for", id).text(t))
                                .disableSelect();
                            li.children(":checkbox").get(0).hideFocus = true;
                            li.children("label").get(0).hideFocus = true;

                            // 找到父结点并插入
                            pv = parseInt(v / 100);
                            var pLi = context.find("li:has(>#P_" + pv + ")");   // parent is a li
                            if (pLi.length === 0) {
                                pLi = context;
                            }
                            var ul = pLi.children("ul");
                            if (ul.length === 0) {
                                ul = $("<ul>").appendTo(pLi);
                            }

                            return li.appendTo(ul); ;
                        };

                        $xml.find("datas > data").each(function () {
                            createLi($(this), root);
                        });

                        context.find(":checkbox").change(function () {
                            var ul = $(this).parentsUntil("ul").parent("ul");
                            var cs = ul.children().children(":checkbox");
                            ul.siblings(":checkbox").attr("checked",
                                cs.length === cs.filter(":checked").length).change();
                        });

                        context.find("li:has(ul)").children("label").click(function () {
                            $(this).siblings("ul").toggle();
                            var t = $(this).text().replace(/[→↓]\s*$/,
                                $(this).siblings("ul").is(":hidden") ? "→" : "↓");
                            $(this).text(t);
                        }).removeAttr("for").css({
                            "font-weight": "bold",
                            "cursor": "pointer"
                        }).each(function () {
                            $(this).text($(this).text() + " ↓");
                        }).end().children(":checkbox").click(function () {
                            $(this).siblings("ul").find(":checkbox")
                                .attr("checked", !!$(this).attr("checked"));
                        });

                        context.find("li:not(:has(ul))").children("label")
                            .end().children(":checkbox");

                        context.appendTo(d.children(".content").empty());

                        initPerms();
                    })
                    // ↑如果列表为空则加载权限，加载完成后初始化权限
                } else {
                    // 列表不为空，初始化权限
                    initPerms();
                }

                overlay.events = {
                    callback: (typeof callback === "function" ? callback : noop)
                };

                overlay.load();
            },

            // 登录/验证用户对话框 /////////////////////////////////////
            login: function (callback) {
                var d = $(".dialogs .login.dialog");
                var overlay = this.login.overlay;
                if (!overlay) {
                    d.find(".buttons a").each(function () {
                        this.hideFocus = true;
                    });

                    overlay = this.login.overlay = d.overlay(this.option({
                        close: ".b_cancel"
                    }));

                    d.find(".b_ok").unbind("click").click(function () {
                        if (!!overlay.isOkClicked) {
                            return;
                        }
                        overlay.isOk = true;
                        overlay.isOkClicked = true;

                        var username = $.trim(d.find("#username").val());
                        var password = d.find("#password").val();
                        if (username.length != 11) {
                            alert("代码长度不正确，请输入11位税务人员代码。");
                            return;
                        }

                        var me = this;
                        app.ajaxXml("core/bll/税务机关和人员.ashx", {
                            "fi_act": "VerifyUser",
                            "username": username,
                            "password": password,
                            "_R": Math.random()
                        }, function (xml) {
                            if (!xml) {
                                alert("验证失败，请检查代码和密码并重新验证");
                                overlay.events.callback(null);
                                return;
                            }

                            overlay.events.callback($(xml));
                            overlay.close();
                        });
                    });

                    d.find("#username").keypress(function (e) {
                        if (e.keyCode !== 13) { return; }
                        if ($(this).val() === "") { return; }

                        d.find("#password").focus();
                    }).keydown(function (e) {
                        if (isCtrlKey(e.keyCode)) { return true; }
                        return /\d/.test(keyChar(e));
                    });

                    d.find("#password").keypress(function (e) {
                        if (e.keyCode !== 13) { return; }
                        d.find(".b_ok").click();
                    });
                }

                overlay.isOk = false;
                overlay.isOkClicked = false;
                overlay.events = {
                    callback: (typeof callback === "function" ? callback : noop)
                };

                d.find(":input").val("");
                overlay.load();
                d.find("#username").focus();
            }
        };
    })();

    // 显示系统错误消息 ////////////////////////////////////////////////////
    (function () {
        app.sysError = function (code, message) {
            switch (code) {
                case -1:
                    return true;
                case -128:
                    app.dialog.message("对不起，您没有权限进行该操作。如果是管理刚刚为您分配了权限，请重新登录之后再试。");
                    break;
                case -127:
                    app.dialog.message(true, "对不起，您的登录已经失效，<br/>可能是由于长时间没有操作造成的。<br/>请重新登录？", function () {
                        window.location.href = "index.html";
                    });
                    break;
                default:
                    app.dialog.message("发生错误：" + message);
                    return true; ;
            }
            return false;
        };
    })();

    // 初始化应用 //////////////////////////////////////////////////////////
    (function () {
        // 执行初始化
        app.init = function () {
            $.each(app.init.funcs, function (index, func) {
                func();
            });
        };

        app.init.funcs = [
            // 字符串本地化 ////////////////////////////////////////////
            function () {
                $.tools.dateinput.localize("cn", {
                    months: "一月,二月,三月,四月,五月,六月,七月,八月,九月,十月,十一月,十二月",
                    shortMonths: "1,2,3,4,5,6,7,8,9,10,11,12",
                    days: "星期天,星期一,星期二,星期三,星期四,星期五,星期六",
                    shortDays: "日,一,二,三,四,五,六"
                });
            },

            // 初始化鼠标Hover事件 /////////////////////////////////////
            function () {
                $(".user_panel .button").hoverable();
                $(".menu_panel li:not(.spliter):not(.group)").hoverable();
                $(".menu_panel li.group div").hoverable();
            },

            // 初始化按钮事件 //////////////////////////////////////////
            function () {
                $(".top_arrow").click(function () {
                    if ($(this).is(".to_left")) {
                        $(this).removeClass("to_left").addClass("to_right");
                        $(".left_area").hide();
                    } else {
                        $(this).removeClass("to_right").addClass("to_left");
                        $(".left_area").show();
                    }
                });
            },

            // 初始化菜单 //////////////////////////////////////////////
            function () {
                $(".menu_panel li").disableSelect();

                $(".menu_panel li.group div").click(function () {
                    $(this).toggleClass("selected");
                    var t = $(this).text().replace(/[→↓]\s*$/, "");
                    if ($(this).is(".selected")) {
                        $(this).text(t + "↓");
                        $(this).parent().find("ul").show();
                    } else {
                        $(this).text(t + "→");
                        $(this).parent().find("ul").hide();
                    }
                });

                $(".menu_panel li[key]").click(function () {
                    var key = $(this).attr("key");
                    var url = window.location.href.replace(/#.+$/, "");
                    if (!!page) {
                        page.applyUrl(url + "#" + key);
                    }
                });
            },

            // 初始化个人信息按钮，及加载用户信息 //////////////////////
            function () {
                $(".user_info_button").click(function () {
                    app.dialog.changePassword();
                });

                $(".user_exit_button").click(function () {
                    app.dialog.confirm("是否退出本系统", function () {
                        app.ajaxXml("core/bll/税务机关和人员.ashx",
                            { fi_act: "Logout" }, function () {
                                window.location.href = "index.html";
                            });
                    });
                });
            },

            // 初始化窗口及部件的大小 //////////////////////////////////
            function () {
                window.loadedAppPage = true;
                setTimeout(function () {
                    $(window).resize();
                }, 200);
            }
        ];  // app.init.funcs
    })();

    // 一些工具函数 ////////////////////////////////////////////////////////
    (function () {
        // 从XML解析用户信息 ///////////////////////////////////////////
        app.setUser = function ($xml) {
            this.userinfo = {
                id: $xml.find("税务人员代码").text(),
                name: $xml.find("税务人员姓名").text(),
                departId: $xml.find("税务机关代码").text(),
                department: $xml.find("税务机关").text(),
                perm: $xml.find("权限").text()
            };

            $(".user_panel .user_name").text(this.userinfo.name);
        };
    })();
})(jQuery, window);
